package springmvc.param.controller;

import springmvc.param.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * description: 02
 * TODO：接收前端的param参数，@RequestParam 指定接收的param参数属性、集合接值、实体类接值
 *
 * @Controller 用于扫描时注册到IOC容器
 *
 * 1. 直接接值
 * 在Handler的形参列表，直接填写URL中对应的参数名称即可
 * 要求名称相同，如果URL中不传参，不报错
 * 如果参数是 int 类型，如 int age，在访问URL中必须要传入 age， ?age=12
 *
 * 2. 注解接值
 * @RequestParam()
 * 用法：用于方法的形参列表中，形参之前，对紧邻的形参生效
 * 作用：指定URL请求参数名、要求参数是否必须传递、不必须传参赋默认值
 * 属性：
 * value 指定URL中的参数名，可以与方法的形参不一致 @RequestParam(value="account") String userid，如果一致可以省略
 * required 指定URL中的参数是否必须，默认为 true，不传报错400。必须和 defaultValue 一起使用
 * defaultValue 当URL中的参数为非必须时，设置默认值。@RequestParam(required=false, defaultValue="18") int age
 *
 * 3. 集合接值
 * URL中存在相同的参数名，但对应多个不同值时，方法的形参使用集合进行接值
 * 形参为集合时，必须使用 @RequestParam 修饰，如果不加会直接将URL中的一个参数值直接赋值给集合，导致类型异常报错
 *
 * 4. 实体类接值
 * 要求实体类的属性名必须和URL中的参数名一致
 * 要求类的属性必须有get、set方法
 * 不强制要求URL中的参数传值，可以在类定义中赋默认值
 */

@Controller
@RequestMapping("param")
public class ParamController {

    // 直接接收，URL：http://localhost:8080/param/data?name=xx&age=18
    @RequestMapping("data")
    @ResponseBody
    public String data(String name, String age){
        System.out.println("name = " + name + ", age = " + age);
        return "name = " + name + ", age = " + age;  // name = xx, age = 18
    }

    // 注解指定, URL： http://localhost:8080/param/data1?account=root&page=1
    // account必须传递，page可以不必须传递，如果不传递默认值就是18
    @GetMapping("data1")
    @ResponseBody
    public String data1(@RequestParam(value = "account") String userid,
                        @RequestParam(required = false, defaultValue = "18") int page){
        System.out.println("username = " + userid + ", page = " + page);
        return "username = " + userid + ", page = " + page; // username = root, page = 1
    }

    // 特殊值，URL：http://localhost:8080/param/data2?hbs=eat&hbs=drink&hbs=play
    // 相同的形参，包含多个不同的值时，使用集合接值。且必须有@RequestParam修饰。
    @GetMapping("data2")
    @ResponseBody
    public String data2(@RequestParam List<String> hbs){
        System.out.println("hbs = " + hbs);
        return hbs.toString();  // [eat, drink, play]
    }

    // 对象接值，URL：http://localhost:8080/param/data3?name=xfanonymous&age=18
    @RequestMapping("data3")
    @ResponseBody
    public String data3(User user){
        System.out.println("user = " + user);
        return user.toString(); // User(name=xfanonymous, id=0, age=18)
    }
}
